package com.zeng.bean.restmodel;

import com.zeng.annotation.restmodel.RestModelField;
import com.zeng.pojo.restmodel.BaseRestModel;
import com.zeng.util.GenUtils;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 字段查询信息
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class RestQueryPropParam {

    // region 关系常量

    public static final String EQUAL = "=";
    public static final String NOT_EQUAL = "!=";
    public static final String GREATER_THAN = ">";
    public static final String GREATER_THAN_EQUAL = ">=";
    public static final String LESS_THAN = "<";
    public static final String LESS_THAN_EQUAL = "<=";
    public static final String LIKE = "like";
    public static final String NOT_LIKE = "not like";
    public static final String IN = "in";
    public static final String NOT_IN = "not in";
    public static final String BETWEEN = "between";
    public static final String NOT_BETWEEN = "not between";
    public static final String IS_NULL = "is null";
    public static final String IS_NOT_NULL = "is not null";

    public static final String[] RELATIONS = {
            EQUAL, NOT_EQUAL, GREATER_THAN, GREATER_THAN_EQUAL,
            LESS_THAN, LESS_THAN_EQUAL, LIKE, NOT_LIKE,
            IN, NOT_IN, BETWEEN, NOT_BETWEEN,
            IS_NULL, IS_NOT_NULL
    };

    public static final String AND = "and";
    public static final String OR = "or";

    public static final String[] JOINRELATIONS = {
            AND, OR
    };

    // endregion

    /**
     * 字段名称
     */
    private String name;

    /**
     * 字段值
     */
    private Object value;

    /**
     * 字段关系
     */
    private String relation = EQUAL;

    private String joinRelation = AND;

    public RestQueryPropParam(String name, Object value) {
        this.name = name;
        this.value = value;
    }

    public void setJoinRelation(String joinRelation) {
        if(Arrays.stream(JOINRELATIONS).noneMatch(joinRelation::equalsIgnoreCase)) {
            throw new IllegalArgumentException("非法的where筛选连接符：" + joinRelation);
        }

        this.joinRelation = joinRelation;
    }

    /**
     * 主类信息
     */
    private Class<? extends BaseRestModel> tbClass;

    /**
     * 字段类型信息
     */
    private Class<?> clazz;

    public void setName(String name) throws Exception {
        if(tbClass == null) {
            throw new Exception("未注册模型类，不可对参数进行赋值");
        }

        Field[] declaredFields = tbClass.getDeclaredFields();
        if(Arrays.stream(declaredFields).noneMatch(declaredField -> declaredField.getName().equalsIgnoreCase(name))){
            throw new IllegalArgumentException("非法的字段名：" + name);
        };

        this.name = name;
    }

    public void setRelation(String relation) {
        if(Arrays.stream(RELATIONS).noneMatch(s -> s.equals(relation.toLowerCase()))){
            throw new IllegalArgumentException("非法的sql关系符" + relation);
        };

        this.relation = relation;
    }


    public static List<RestQueryPropParam> getAllFields(Class<? extends BaseRestModel> clazz) throws Exception {
        List<RestQueryPropParam> result = new ArrayList<>();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            String filedName = field.getName();
            RestQueryPropParam param = new RestQueryPropParam();
            param.setTbClass(clazz);
            param.setClazz(field.getType());

            RestModelField annotation = field.getAnnotation(RestModelField.class);

            if(annotation != null) {
                if(annotation.ignore())continue;
                if(!GenUtils.stringIsNullOrWhiteSpace(annotation.name())) {
                    filedName = annotation.name();
                }
            }

            param.setName(filedName);
            result.add(param);
        }
        return result;
    }
}
